package com.hfh.main.group.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hfh.main.common.annotate.JwtToken;
import com.hfh.main.common.resp.Result;
import com.hfh.main.common.utils.OSSUtil;
import com.hfh.main.course.entity.CourseListEntity;
import com.hfh.main.course.service.CourseListService;
import com.hfh.main.group.entity.*;
import com.hfh.main.group.mapper.GroupMapper;
import com.hfh.main.group.service.GroupDetailService;
import com.hfh.main.group.service.GroupService;
import com.hfh.main.report.entity.DailyReportEntity;
import com.hfh.main.report.entity.WeekEntity;
import com.hfh.main.report.service.DailyReportService;
import com.hfh.main.report.service.WeekService;
import com.hfh.main.report.service.impl.DailyReportServiceImpl;
import com.hfh.main.user.entity.UserEntity;
import com.hfh.main.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 分组管理
 */
@Tag(name = "分组管理")
@RestController
@RequestMapping("/groupEntity")
public class GroupController {

    @Autowired
    private GroupMapper groupMapper;
    @Autowired
    private GroupService groupService;
    @Autowired
    private GroupDetailService groupDetailService;
    @Autowired
    private UserService userService;
    @Autowired
    private CourseListService courseListService;
    @Autowired
    private WeekService weekService;

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Autowired
    private DailyReportService dailyReportService;

    @JwtToken
    @Operation(summary = "组主表-列表-分页")
    @PostMapping("/listPageGroup")
    public Result<?> listPageGroupList(@RequestParam Integer page, @RequestParam Integer pageSize) {
        //分页参数
        Page<GroupEntity> rowPage = new Page(page, pageSize);
        //queryWrapper组装查询where条件
        LambdaQueryWrapper<GroupEntity> queryWrapper = new LambdaQueryWrapper<>();
        rowPage = groupMapper.selectPage(rowPage, queryWrapper);
        //根据编号查组长
        List<GroupEntity> records = rowPage.getRecords();
        List<GroupEntity> collect = supplementList(records);
        rowPage.setRecords(collect);
        return Result.success("数据请求成功", rowPage);
    }

    @JwtToken
    @Operation(summary = "组主表-查询-编号")
    @PostMapping("/selectGroupByID/{param}")
    public Result<?> selectGroupByID(@PathVariable @Validated String param) {
        QueryWrapper<GroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(("group_id"), param);
        if (groupService.count(wrapper) == 0) return Result.failure(200, "编号不存在", sdf.format(new Date()));
        return Result.success(supplement(groupService.getOne(wrapper)));
    }

    @JwtToken
    @Operation(summary = "组主表-查询-名称")
    @PostMapping("/selectGroupByName/{param}")
    public Result<?> selectGroupByName(@PathVariable @Validated String param) {
        QueryWrapper<GroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(("group_name"), param);
        if (groupService.count(wrapper) == 0) return Result.failure(200, "名称不存在", sdf.format(new Date()));
        return Result.success(supplement(groupService.getOne(wrapper)));
    }

    @JwtToken
    @Operation(summary = "组主表-保存")
    @PostMapping("/insert")
    public Result<?> insertGroup(@RequestBody @Validated GroupEntity entity) {
        QueryWrapper<GroupEntity> wrapper = new QueryWrapper<>();
        if (entity.getGroupName() != null && entity.getGroupName().length() != 0)
            wrapper.or().like("group_name", entity.getGroupName());
        if (entity.getGroupNo() != null && entity.getGroupNo().length() != 0)
            wrapper.or().eq("group_no", entity.getGroupNo());
        if (groupService.count(wrapper) != 0)
            return Result.failure(200, "相同编号或名称的小组已存在！", sdf.format(new Date()));

        QueryWrapper<GroupEntity> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("user_acc", entity.getAcc());
        if (groupService.count(wrapper2) != 0)
            return Result.failure(200, "已存在相同组长的组！", sdf.format(new Date()));

        groupService.save(entity);
        groupDetailService.save(GroupDetailEntity.builder().groupId(entity.getId()).acc(entity.getAcc()).build());
        //对身份进行修改
        UserEntity userEntity = new UserEntity();
        userEntity.setAcc(entity.getAcc());
        userService.updateRoleByAcc(userEntity);

        groupService.updateById(entity);

        //更新最终分数
        groupService.calculateStudentFinalScore(entity);

        return Result.success("保存成功", sdf.format(new Date()));
    }

    @JwtToken
    @Operation(summary = "组主表-删除")
    @PostMapping("/delete/{param}")
    public Result<?> deleteGroup(@PathVariable @Validated String param) {
        QueryWrapper<GroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(("group_id"), param);
        if (groupService.count(wrapper) == 0) return Result.failure(200, "编号不存在", sdf.format(new Date()));
        GroupEntity one = groupService.getOne(wrapper);
        String groupNo = one.getGroupNo();
        groupService.remove(wrapper);
        QueryWrapper<GroupDetailEntity> wrapper2 = new QueryWrapper<>();
        wrapper2.eq(("group_id"), groupNo);
        groupDetailService.remove(wrapper2);
        return Result.success("保存成功", sdf.format(new Date()));
    }

    @JwtToken
    @Operation(summary = "组主表-修改")
    @PostMapping("/update")
    public Result<?> updateGroup(@RequestBody @Validated GroupEntity entity) {
        //这个方法不让修改组长!!!
        QueryWrapper<GroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(("group_id"), entity.getId());
        if (groupService.count(wrapper) == 0) return Result.failure(200, "编号不存在", sdf.format(new Date()));
        //这个地方需要判断是否修改编号 I think do not need
//        GroupEntity entityById = groupService.getById(entity.getId());
//        String groupNo = entity.getGroupNo();
//        String groupNoById = entityById.getGroupNo();
//        //如果编号没有修改
//        if (groupNo.equals(groupNoById)) {
        if (groupService.updateById(entity)) {
            //更新最终分数
            groupService.calculateStudentFinalScore(entity);

            return Result.success("修改成功", sdf.format(new Date()));
        }
//        } else {
//            groupService.updateById(entity);
//            QueryWrapper<GroupDetailEntity> wrapper2 = new QueryWrapper<>();
//            wrapper2.eq(("group_id"), groupNoById);
//            groupDetailService.update(GroupDetailEntity.builder().groupId(entity.getId()).build(), wrapper2);
//            return Result.success("修改成功", sdf.format(new Date()));
//        }
        return Result.failure(200, "修改失败", sdf.format(new Date()));
    }

    private @NotNull List<GroupEntity> supplementList(List<GroupEntity> records) {
        List<GroupEntity> collect = records.stream().map(m -> {
            //根据学号查名字，查项目
            String acc = m.getAcc();
            if (StrUtil.isNotEmpty(acc)) {
                UserEntity userEntity = userService.queryByAcc(acc);
                m.setLeader(userEntity.getName());
                m.setAcc(acc);
            }
            if (StrUtil.isNotEmpty(m.getListId())) {
                CourseListEntity courseListEntity = courseListService.queryCourseByListId(m.getListId());
                m.setListNo(courseListEntity.getNo());
                m.setListName(courseListEntity.getName());
            }
            return m;
        }).toList();
        return collect;
    }

    private @NotNull GroupEntity supplement(GroupEntity r) {
        //根据学号查名字，查项目
        String acc = r.getAcc();
        if (StrUtil.isNotEmpty(acc)) {
            UserEntity userEntity = userService.queryByAcc(acc);
            r.setLeader(userEntity.getName());
            r.setAcc(acc);
        }
        if (StrUtil.isNotEmpty(r.getListId())) {
            CourseListEntity courseListEntity = courseListService.queryCourseByListId(r.getListId());
            r.setListNo(courseListEntity.getNo());
            r.setListName(courseListEntity.getName());
        }
        return r;
    }


    @JwtToken
    @Operation(summary = "组-导出")
    @PostMapping("/export/{param}")
    public void export(@PathVariable @Validated String param, HttpServletResponse response) throws IOException {
        QueryWrapper<GroupEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_acc", param);
        GroupEntity one = groupService.getOne(wrapper);
        if (one == null) {
            return ;
        }
        //第一个sheet页
        String groupName = one.getGroupName();
        Double dbFirst = one.getDbFirst();
        Double dbSecond = one.getDbSecond();
        Double dbMid = one.getDbMid();
        Double dbTerminal = one.getDbTerminal();
        ExportOverview build = ExportOverview.builder().dbFirst(String.valueOf(dbFirst)).dbSecond(String.valueOf(dbSecond)).dbMid(String.valueOf(dbMid)).dbTerminal(String.valueOf(dbTerminal)).build();
        List<ExportOverview> listExportOverview = Collections.singletonList(build);


        //查询每个组员
        Integer id = one.getId();
        QueryWrapper<GroupDetailEntity> wrapperD = new QueryWrapper<>();
        wrapperD.eq("group_id", id);
        List<GroupDetailEntity> detailList = groupDetailService.list(wrapperD);

        List<ExportWeek> listExportWeek = new ArrayList<ExportWeek>();
        detailList.forEach(e -> {
            QueryWrapper<WeekEntity> wrapperE = new QueryWrapper<>();
            wrapperE.eq("user_acc", e.getAcc());
            List<WeekEntity> list = weekService.list(wrapperE);

            UserEntity userEntity = userService.queryByAcc(e.getAcc());

            //组长打的周平分，
            if (CollectionUtil.isNotEmpty(list)) {
                WeekEntity weekEntity1 = list.stream().filter(f -> f.getWeekNumber() == 1).findFirst().get();
                WeekEntity weekEntity2 = list.stream().filter(f -> f.getWeekNumber() == 2).findFirst().get();
                WeekEntity weekEntity3 = list.stream().filter(f -> f.getWeekNumber() == 3).findFirst().get();
                WeekEntity weekEntity4 = list.stream().filter(f -> f.getWeekNumber() == 4).findFirst().get();
                Double weekScore1 = weekEntity1.getWeekScore();
                Double weekScore2 = weekEntity2.getWeekScore();
                Double weekScore3 = weekEntity3.getWeekScore();
                Double weekScore4 = weekEntity4.getWeekScore();
                ExportWeek exportWeek = ExportWeek.builder().name(userEntity.getName()).acc(userEntity.getAcc())
                        .weekScore1(String.valueOf(weekScore1)).weekScore2(String.valueOf(weekScore2)).weekScore3(String.valueOf(weekScore3)).weekScore4(String.valueOf(weekScore4))
                        .build();
                listExportWeek.add(exportWeek);
            }
        });

        List<ExportDay> listExportDay = new ArrayList<ExportDay>();
        detailList.forEach(e -> {
            LambdaQueryWrapper<DailyReportEntity> wrapperR = new LambdaQueryWrapper<>();
            wrapperR.eq(DailyReportEntity::getAcc, e.getAcc());
            wrapperR.orderByAsc(DailyReportEntity::getDate);
            List<DailyReportEntity> list = dailyReportService.list(wrapperR);
            list.stream().forEach(l->{
                UserEntity userEntity = userService.queryByAcc(l.getAcc());
                ExportDay day = ExportDay.builder().name(userEntity.getName()).acc(userEntity.getAcc()).score(String.valueOf(l.getSelfEval())).date(l.getDate()).build();
                listExportDay.add(day);
            });
        });


        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(groupName + "-评分导出", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
        WriteSheet exportOverviewSheet = EasyExcel.writerSheet(groupName).head(ExportOverview.class).build();
        WriteSheet exportWeekSheet = EasyExcel.writerSheet("周评分").head(ExportWeek.class).build();
        WriteSheet exportDaySheet = EasyExcel.writerSheet("日评分").head(ExportDay.class).build();
        excelWriter.write(listExportOverview, exportOverviewSheet);
        excelWriter.write(listExportWeek, exportWeekSheet);
        excelWriter.write(listExportDay, exportDaySheet);
        excelWriter.finish();
        return ;
    }

}
